/*
 * Copyright 2006 - Chris Maki
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.agoracms.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="post")
@NamedQueries( { 
	@NamedQuery(name="post.parentPosts", query = "select p from Post p where p.parent is empty"),
	@NamedQuery(name="post.findPost", query="select p from Post p where p.forum = :forum AND p.topic = :topic AND p.title = :title")
} )
public class Post extends ModelBase {

	@Lob
	@Column(name="content")
	private String content;
	
	private String title;
	
	@Column(name="edit_count")
	private Integer editCount;

	@ManyToOne
	private Post parent;
	
	@ManyToOne
	private Topic topic;
	
	@OneToOne
	private Forum forum;

	// TODO: when we fetch a Post we also want its children so you'll want to
	// remove the lazy once the JPQL chapter is done
	@OneToMany(cascade=CascadeType.PERSIST, fetch=FetchType.LAZY)
	private Set<Post> children = new HashSet<Post>();
	
	// we will store the numeric value of the type in the be, makes sorting more
	// consistent
	@Enumerated(value=EnumType.ORDINAL)
	private FTPType type = FTPType.NORMAL;
	
	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public Integer getEditCount() {
		return editCount;
	}

	public void setEditCount(Integer editCount) {
		this.editCount = editCount;
	}

	public Post getParent() {
		return parent;
	}

	public void setParent(Post parent) {
		this.parent = parent;
		parent.addChildPost(this);
		
	}

	public Topic getTopic() {
		return topic;
	}

	public void setTopic(Topic topic) {
		this.topic = topic;
	}

	public FTPType getType() {
		return type;
	}

	public void setType(FTPType type) {
		this.type = type;
	}

	public Forum getForum() {
		return forum;
	}

	public void setForum(Forum forum) {
		this.forum = forum;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((content == null) ? 0 : content.hashCode());
		result = PRIME * result + ((title == null) ? 0 : title.hashCode());
		result = PRIME * result + ((parent == null) ? 0 : parent.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Post))
			return false;
		final Post other = (Post) obj;
		if (content == null) {
			if (other.getContent() != null)
				return false;
		} else if (!content.equals(other.content))
			return false;
		if (title == null) {
			if (other.getTitle() != null)
				return false;
		} else if (!title.equals(other.getTitle()))
			return false;
		if (parent == null) {
			if (other.getParent() != null)
				return false;
		} else if (!parent.equals(other.getParent()))
			return false;
		return true;
	}

	public Set<Post> getChildren() {
		return children;
	}

	public void setChildren(Set<Post> children) {
		this.children = children;
	}

	public boolean addChildPost(Post o) {
		return children.add(o);
	}

	public boolean removeChildPost(Post o) {
		return children.remove(o);
	}
	
	
}
